vcl 4.0;

import directors;

backend wiki {
    .host = "localhost";
    .port = "10001";
    .first_byte_timeout = 120s;
}

backend mirrorlists {
    .host = "localhost";
    .port = "10002";
}

backend pkgdb {
    .host = "localhost";
    .port = "10003";
    .first_byte_timeout = 160s;
}

backend mailman {
    .host = "mailman01";
    .port = "http";
    .first_byte_timeout = 180s;
    .probe = {
        .url = "/";
        .interval = 5s;
        .timeout = 5s;
	.expected_response = 301;
    }
}

backend fas01 {
    .host = "fas01";
    .port = "http";
    .probe = {
        .url = "/accounts/";
        .interval = 5s;
        .timeout = 5s;
        .window = 5;
        .threshold = 5;
    }
}

backend fas02 {
    .host = "fas02";
    .port = "http";
    .probe = {
        .url = "/accounts/";
        .interval = 5s;
        .timeout = 5s;
        .window = 5;
        .threshold = 5;
    }
}

backend fas03 {
    .host = "fas03";
    .port = "http";
    .probe = {
        .url = "/accounts/";
        .interval = 5s;
        .timeout = 5s;
        .window = 5;
        .threshold = 5;
    }
}

sub vcl_init {
  new fas = directors.round_robin();
  fas.add_backend(fas01);
  fas.add_backend(fas02);
  fas.add_backend(fas03);
}

backend nuancier {
    .host = "localhost";
    .port = "10035";
}

backend voting {
    .host = "localhost";
    .port = "10007";
    .first_byte_timeout = 160s;
}

backend mirrormanager {
    .host = "localhost";
    .port = "10008";
}

backend bodhi {
    .host = "localhost";
    .port = "10009";
}

backend freemedia {
    .host = "localhost";
    .port = "10011";
}

backend packages {
    .host = "localhost";
    .port = "10016";
}

backend tagger {
    .host = "localhost";
    .port = "10017";
}

backend askbot {
    .host = "localhost";
    .port = "10021";
}

backend blockerbugs {
    .host = "localhost";
    .port = "10022";
}

backend fedocal {
    .host = "localhost";
    .port = "10023";
}

backend kerneltest {
    .host = "localhost";
    .port = "10038";
}

backend paste {
    .host = "localhost";
    .port = "10055";
}

backend koschei {
    .host = "localhost";
    .port = "10040";
}

backend registry {
    .host = "localhost";
    .port = "10048";
}


acl purge {
    "192.168.1.129"; // wiki01.vpn
    "192.168.1.130"; // wiki02.vpn
    "10.5.128.188"; // wiki01.stg
    "10.5.126.63"; // wiki01
    "10.5.126.73"; // wiki02
    "10.5.126.23"; // lockbox01
    "192.168.1.58"; //lockbox01.vpn
}

sub vcl_synth {
    set resp.http.Content-Type = "text/html; charset=utf-8";
    set resp.http.Retry-After = "5";
    synthetic( {"<!DOCTYPE html>
<html>
  <head>
    <title>"} + resp.status + " " + resp.reason + {"</title>
  </head>
  <body>
    <h1>Error "} + resp.status + " " + resp.reason + {"</h1>
    <p>"} + resp.reason + {"</p>
    <h3>Guru Meditation:</h3>
    <p>XID: "} + req.xid + {"</p>
    <hr>
    <p>Varnish cache server on {{ inventory_hostname }}</p>
  </body>
</html>
"} );
    return (deliver);
}

# CAUTIN: Make very sure that for every unset req.http.cookie, you
# also set a req.http.clear-cookies = "yes", and in *no other case*.
# This is done to prevent the case where Varnish drops the cookies
# because this is the efficient thing to do to allow more caching,
# but then the backend sends a new session cookies back, overwriting
# the one the browser had already.
sub vcl_recv {
    if (req.method == "PURGE") {
        if (!client.ip ~ purge) {
            return (synth(405, "Not allowed"));
        }
        return(purge);
    }

    if (req.http.X-Forwarded-Server ~ "^registry.fedoraproject.org" || req.http.X-Forwarded-Server ~ "^registry.stg.fedoraproject.org") {
        set req.backend_hint = registry;
        unset req.http.cookie;
        set req.http.clear-cookies = "yes";
        set req.url = regsub(req.url, "\?.*", "");
        if (req.url ~ "/blobs/") {
            return(pass);
        }
    }
    if (req.url ~ "^/wiki/") {
        set req.backend_hint = wiki;
    }
    if (req.url ~ "^/w/") {
        set req.backend_hint = wiki;
        if (req.url ~ "^/w/skins/") {
            unset req.http.cookie;
            set req.http.clear-cookies = "yes";
            set req.url = regsub(req.url, "\?.*", "");
        }
    }
    if (req.url ~ "^/mirrorlist/") {
        set req.backend_hint = mirrorlists;
    }
    if (req.url ~ "^/pkgdb") {
        set req.backend_hint = pkgdb;
        if (req.url ~ "^/pkgdb/static/") {
            unset req.http.cookie;
            set req.http.clear-cookies = "yes";
            set req.url = regsub(req.url, "\?.*", "");
        }
    }
    if (req.url ~ "^/accounts/") {
        set req.backend_hint = fas.backend();
        if (req.url ~ "^/accounts/static/") {
            unset req.http.cookie;
            set req.http.clear-cookies = "yes";
            set req.url = regsub(req.url, "\?.*", "");
        }
    }
    if (req.url ~ "^/voting/") {
        set req.backend_hint = voting;
        if (req.url ~ "^/voting/static/") {
            unset req.http.cookie;
            set req.http.clear-cookies = "yes";
            set req.url = regsub(req.url, "\?.*", "");
        }
    }
    if (req.url ~ "^/mirrormanager") {
        set req.backend_hint = mirrormanager;
        if (req.url ~ "^/mirrormanager/static/") {
            unset req.http.cookie;
            set req.http.clear-cookies = "yes";
            set req.url = regsub(req.url, "\?.*", "");
        }
        if (req.url ~ "^/mirrormanager/mirrors") {
            unset req.http.cookie;
            set req.http.clear-cookies = "yes";
            set req.url = regsub(req.url, "\?.*", "");
        }
    }
    if (req.url ~ "^/updates/") {
        set req.backend_hint = bodhi;
        if (req.url ~ "^/updates/static/") {
            unset req.http.cookie;
            set req.http.clear-cookies = "yes";
            set req.url = regsub(req.url, "\?.*", "");
        }
    }
    if (req.url ~ "^/freemedia/") {
        set req.backend_hint = freemedia;
    }
    if (req.url ~ "^/tagger/") {
        set req.backend_hint = tagger;
        if (req.url ~ "^/tagger/ui/static/") {
            unset req.http.cookie;
            set req.http.clear-cookies = "yes";
            set req.url = regsub(req.url, "\?.*", "");
        }
    }
    if (req.http.X-Forwarded-Server ~ "^paste.fedoraproject.org") {
        set req.backend_hint = paste;
        if (req.url ~ "^/static/") {
            unset req.http.cookie;
            set req.http.clear-cookies = "yes";
            set req.url = regsub(req.url, "\?.*", "");
        }
    }
    if (req.http.X-Forwarded-Server ~ "^ask.fedoraproject.org") {
        set req.backend_hint = askbot;
        if (req.url ~ "^/m/") {
            unset req.http.cookie;
            set req.http.clear-cookies = "yes";
            set req.url = regsub(req.url, "\?.*", "");
        }
    }
    if (req.http.X-Forwarded-Server ~ "^qa.fedoraproject.org" || req.http.X-Forwarded-Server ~ "^qa.stg.fedoraproject.org") {
        if (req.url ~ "^/blockerbugs") {
             set req.backend_hint = blockerbugs;
            if (req.url ~ "^/blockerbugs/static/") {
                unset req.http.cookie;
                set req.http.clear-cookies = "yes";
                set req.url = regsub(req.url, "\?.*", "");
            }
        }
    }
    if (req.http.X-Forwarded-Server ~ "^lists.fedoraproject.org" || req.http.X-Forwarded-Server ~ "^lists.stg.fedoraproject.org" || req.http.X-Forwarded-Server ~ "^lists.fedorahosted.org" || req.http.X-Forwarded-Server ~ "^lists.stg.fedorahosted.org" ) {
        set req.backend_hint = mailman;
    }
    if (req.http.X-Forwarded-Server ~ "^apps.fedoraproject.org" || req.http.X-Forwarded-Server ~ "^apps.stg.fedoraproject.org") { 
        if (req.url ~ "^/koschei") {
            set req.backend_hint = koschei;
            if (req.url ~ "^/koschei/static/") {
                unset req.http.cookie;
                set req.http.clear-cookies = "yes";
                set req.url = regsub(req.url, "\?.*", "");
            }
        }
        if (req.url ~ "^/kerneltest") {
            set req.backend_hint = kerneltest;
            if (req.url ~ "^/kerneltest/static/") {
                unset req.http.cookie;
                set req.http.clear-cookies = "yes";
                set req.url = regsub(req.url, "\?.*", "");
            }
        }
        if (req.url ~ "^/calendar") {
            set req.backend_hint = fedocal;
            if (req.url ~ "^/calendar/static/") {
                unset req.http.cookie;
                set req.http.clear-cookies = "yes";
                set req.url = regsub(req.url, "\?.*", "");
            }
        }
        if (req.url ~ "^/nuancier") {
            set req.backend_hint = nuancier;
            if (req.url ~ "^/nuancier/static/") {
                unset req.http.cookie;
                set req.http.clear-cookies = "yes";
                set req.url = regsub(req.url, "\?.*", "");
            }
            if (req.url ~ "^/nuancier/cache/") {
                unset req.http.cookie;
                set req.http.clear-cookies = "yes";
                set req.url = regsub(req.url, "\?.*", "");
            }
        }
        if (req.url ~ "^/packages/") {
            set req.backend_hint = packages;
            if (req.url ~ "^/packages/_res/") {
                unset req.http.cookie;
                set req.http.clear-cookies = "yes";
                set req.url = regsub(req.url, "\?.*", "");
            }
            if (req.url ~ "^/packages/css/") {
                unset req.http.cookie;
                set req.http.clear-cookies = "yes";
                set req.url = regsub(req.url, "\?.*", "");
            }
            if (req.url ~ "^/packages/images/") {
                unset req.http.cookie;
                set req.http.clear-cookies = "yes";
                set req.url = regsub(req.url, "\?.*", "");
            }
            if (req.url ~ "^/packages/js/") {
                unset req.http.cookie;
                set req.http.clear-cookies = "yes";
                set req.url = regsub(req.url, "\?.*", "");
            }
        }
    }

    # Pass any requests with the "If-None-Match" header directly.
    if (req.http.If-None-Match) {
        return (pass);
    }

    # Force lookup if the request is a no-cache request from the client.
#    if (req.http.Cache-Control ~ "no-cache") {
#        purge_url(req.url);
#    }
#    if (req.http.Accept-Encoding) {
#        if (req.url ~ "\.(jpg|png|gif|gz|tgz|bz2|tbz|mp3|ogg)$") {
#            # No point in compressing these
#            remove req.http.Accept-Encoding;
#        } elsif (req.http.Accept-Encoding ~ "gzip") {
#            # This is currently a bug with ipv6, so we need to nuke it.
#            remove req.http.Accept-Encoding;
#        } elsif (req.http.Accept-Encoding ~ "deflate") {
#            set req.http.Accept-Encoding = "deflate";
#        } else {
#            # unknown algorithm
#            remove req.http.Accept-Encoding;
#        }
#    }
}

# When requesting application icons, don't allow cherrypy to set cookies
#sub vcl_backend_fetch {
#    if (req.url ~ "^/pkgdb/appicon/show/") {
#        unset beresp.http.set-cookie;
#    }
#}


# Make sure mirrormanager/mirrors doesn't set any cookies
# (Setting cookies would make varnish store a HIT-FOR-PASS
#  making it always fetch from backend)
sub vcl_backend_response {
    if (bereq.url ~ "^/mirrormanager/mirrors") {
        unset beresp.http.set-cookie;
        set beresp.ttl = 6h;
    }
    if (bereq.url ~ "^/mirrormanager/static/") {
        set beresp.ttl = 6h;
    }
}

sub vcl_deliver {
    if (req.http.clear-cookies ~ "yes") {
        # If we stored that we cleared request cookies, we also make sure
        # we are not sending any response cookies.
        # NOTE: this is suboptimal, since clearing them at this time means
        # varnish has already cached that this endpoint returns cookies and
        # will not cache it. This is really just a failsafe to make sure we
        # don't send empty cookies back.
        unset resp.http.set-cookie;
    }
}

sub vcl_pipe {
        set req.http.connection = "close";
}

sub vcl_hit {
        if (req.method == "PURGE") {
            ban(req.url);
            return (synth(200, "Purged"));
        }
 
        if (!obj.ttl > 0s) {
            return (pass);
        }
}
 
sub vcl_miss {
        if (req.method == "PURGE")  {
            return (synth(200, "Not in cache"));
        }
}
